/* 
 * "Small Hello World" example. 
 * 
 * This example prints 'Hello from Nios II' to the STDOUT stream. It runs on
 * the Nios II 'standard', 'full_featured', 'fast', and 'low_cost' example 
 * designs. It requires a STDOUT  device in your system's hardware. 
 *
 * The purpose of this example is to demonstrate the smallest possible Hello 
 * World application, using the Nios II HAL library.  The memory footprint
 * of this hosted application is ~332 bytes by default using the standard 
 * reference design.  For a more fully featured Hello World application
 * example, see the example titled "Hello World".
 *
 * The memory footprint of this example has been reduced by making the
 * following changes to the normal "Hello World" example.
 * Check in the Nios II Software Developers Manual for a more complete 
 * description.
 * 
 * In the SW Application project (small_hello_world):
 *
 *  - In the C/C++ Build page
 * 
 *    - Set the Optimization Level to -Os
 * 
 * In System Library project (small_hello_world_syslib):
 *  - In the C/C++ Build page
 * 
 *    - Set the Optimization Level to -Os
 * 
 *    - Define the preprocessor option ALT_NO_INSTRUCTION_EMULATION 
 *      This removes software exception handling, which means that you cannot 
 *      run code compiled for Nios II cpu with a hardware multiplier on a core 
 *      without a the multiply unit. Check the Nios II Software Developers 
 *      Manual for more details.
 *
 *  - In the System Library page:
 *    - Set Periodic system timer and Timestamp timer to none
 *      This prevents the automatic inclusion of the timer driver.
 *
 *    - Set Max file descriptors to 4
 *      This reduces the size of the file handle pool.
 *
 *    - Check Main function does not exit
 *    - Uncheck Clean exit (flush buffers)
 *      This removes the unneeded call to exit when main returns, since it
 *      won't.
 *
 *    - Check Don't use C++
 *      This builds without the C++ support code.
 *
 *    - Check Small C library
 *      This uses a reduced functionality C library, which lacks  
 *      support for buffering, file IO, floating point and getch(), etc. 
 *      Check the Nios II Software Developers Manual for a complete list.
 *
 *    - Check Reduced device drivers
 *      This uses reduced functionality drivers if they're available. For the
 *      standard design this means you get polled UART and JTAG UART drivers,
 *      no support for the LCD driver and you lose the ability to program 
 *      CFI compliant flash devices.
 *
 *    - Check Access device drivers directly
 *      This bypasses the device file system to access device drivers directly.
 *      This eliminates the space required for the device file system services.
 *      It also provides a HAL version of libc services that access the drivers
 *      directly, further reducing space. Only a limited number of libc
 *      functions are available in this configuration.
 *
 *    - Use ALT versions of stdio routines:
 *
 *           Function                  Description
 *        ===============  =====================================
 *        alt_printf       Only supports %s, %x, and %c ( < 1 Kbyte)
 *        alt_putstr       Smaller overhead than puts with direct drivers
 *                         Note this function doesn't add a newline.
 *        alt_putchar      Smaller overhead than putchar with direct drivers
 *        alt_getchar      Smaller overhead than getchar with direct drivers
 *
 */

#include "sys/alt_stdio.h"
#include <system.h>
#include <string.h>
#include "uart.h"
#include <altera_avalon_pio_regs.h>

#define BT_UART	UART_0_BASE


/* reverse:  reverse string s in place */
void reverse(char s[])
{
	int i, j;
	char c;

	for (i = 0, j = strlen(s)-1; i<j; i++, j--) {
		c = s[i];
		s[i] = s[j];
		s[j] = c;
	}
}

/* itoa:  convert n to characters in s */
void itoa(int n, char s[])
{
	int i, sign;

	if ((sign = n) < 0)  /* record sign */
		n = -n;          /* make n positive */
	i = 0;
	do {       /* generate digits in reverse order */
		s[i++] = n % 10 + '0';   /* get next digit */
	} while ((n /= 10) > 0);     /* delete it */
	if (sign < 0)
		s[i++] = '-';
	s[i] = '\0';
	reverse(s);
}

int main()
{ 
	const char* tx = "AT\r";
	char rx[100];

	// Character buffers
	const char* at = "AT\r";
	const char* factoryDefault = "AT&F*\r";
	const char* discoverable = "ATS512=4\r";
	const char* autoAnswer = "ATS0=1\r";
	const char* setPin = "AT+BTK=\"1234\"\r";
	const char* setName = "AT+BTN=\"UoB -- EEG Of Death\"\r";
	const char* save = "AT&W\r";
	const char* softwareReset = "ATZ\r";
	const char* newLine = " ";

	char* data = "Hello World...  ><{{{*>  \r\n";
	char* toSend;
	short validFlag = 0;


	// Result values
	int resultWrite = 0;
	int resultRead = 0;

	alt_putstr("Hello from Nios II!\n");


	// Try and send some data.... (need to fix 3, magic number!)
	resultWrite = write_uart(UART_0_BASE, tx, getTxLength(tx));
	resultRead = read_uart(UART_0_BASE, &rx);


	alt_printf("Bluetooth Said %s\n", rx);

	// Hacked setup...
	resultWrite = write_uart(UART_0_BASE, factoryDefault, getTxLength(factoryDefault));
	resultRead = read_uart(UART_0_BASE, &rx);
	alt_printf("Bluetooth Said %s\n", rx);

	// Hacked setup...
	resultWrite = write_uart(UART_0_BASE, discoverable, getTxLength(discoverable));
	resultRead = read_uart(UART_0_BASE, &rx);
	alt_printf("Bluetooth Said %s\n", rx);

	// Hacked setup...
	resultWrite = write_uart(UART_0_BASE, setName, getTxLength(setName));
	resultRead = read_uart(UART_0_BASE, &rx);
	alt_printf("Bluetooth Said %s\n", rx);

	// Hacked setup...
	resultWrite = write_uart(UART_0_BASE, autoAnswer, getTxLength(autoAnswer));
	resultRead = read_uart(UART_0_BASE, &rx);
	alt_printf("Bluetooth Said %s\n", rx);

	// Hacked setup...
	resultWrite = write_uart(UART_0_BASE, setPin, getTxLength(setPin));
	resultRead = read_uart(UART_0_BASE, &rx);
	alt_printf("Bluetooth Said %s\n", rx);

	// Hacked setup...
	resultWrite = write_uart(UART_0_BASE, save, getTxLength(save));
	resultRead = read_uart(UART_0_BASE, &rx);
	alt_printf("Bluetooth Said %s\n", rx);

	// Hacked setup...
	resultWrite = write_uart(UART_0_BASE, softwareReset, getTxLength(softwareReset));
	resultRead = read_uart(UART_0_BASE, &rx);
	alt_printf("Bluetooth Said %s\n", rx);

	while(1)
	{
		short fromADC = IORD_ALTERA_AVALON_PIO_DATA(PIO_EEG_ADC1_BASE);
		short validSample = IORD_ALTERA_AVALON_PIO_DATA(PIO_EEG_ADC1_NEW_BASE);

		short value;
		char lsb, msb;

		if (validSample == 1)
		{
			// Masking
			// 3F AND input = lower six bits
			// FC0 AND input = upper six bits
			// C0 OR input = Sets second byte header as 01

			lsb = (char)(fromADC & 0x3F);
			msb = (char)((fromADC >> 6) & 0x3F);

			value = (short)(((msb & 0xFF)<<8) + (lsb & 0xFF));
			value = (value | 0xC0);
			//alt_printf("Count is: %x, lsb is %x, msb is %x and value is %x\n", count, lsb, msb, value);

			toSend = value;
			resultWrite = write_uart(UART_0_BASE, &toSend, 2);
			//alt_printf("Sent %x\n", toSend);

			// Wait for next valid sample
			while (IORD_ALTERA_AVALON_PIO_DATA(PIO_EEG_ADC1_NEW_BASE) == 1);
		}

	}


	return 0;
}
